This example mirrors mesh.loader.html with an extra "Clear Layers" button.
In [1]:
from pathlib import Path
from ipyniivue import download_dataset
BASE_API_URL = "https://niivue.com/demos/images"
DATA_FOLDER = Path("images")
# Download data for example
download_dataset(
BASE_API_URL,
DATA_FOLDER,
files=[
"BrainMesh_ICBM152.lh.mz3",
"CIT168.mz3",
"BrainMesh_ICBM152.lh.motor.mz3",
],
)
BrainMesh_ICBM152.lh.mz3 already exists. Downloading CIT168.mz3... BrainMesh_ICBM152.lh.motor.mz3 already exists. Dataset downloaded successfully to images.
In [2]:
import ipywidgets as widgets
from IPython.display import display
from ipyniivue import Mesh, MeshLayer, NiiVue
# 1. Initialize NiiVue
nv = NiiVue()
nv.opts.show_3d_crosshair = True
nv.opts.back_color = (1, 1, 1, 1)
nv.opts.mesh_xray = 0.3
nv.opts.show_legend = False
nv.opts.is_colorbar = True
# 2. Define the initial meshes
mesh_hemisphere = Mesh(
path=DATA_FOLDER / "BrainMesh_ICBM152.lh.mz3",
rgba255=[255, 255, 255, 255],
layers=[],
)
mesh_cit = Mesh(path=DATA_FOLDER / "CIT168.mz3", rgba255=[0, 0, 255, 255])
# Load meshes into the scene
nv.meshes = [mesh_hemisphere, mesh_cit]
# 3. Create UI Controls
# XRay Slider
xray_slider = widgets.FloatSlider(
min=0, max=0.5, value=0.3, step=0.01, description="XRay"
)
# Hemisphere Visible Checkbox
vis_checkbox = widgets.Checkbox(value=True, description="Hemisphere Visible")
# Add Layer Buttons
clear_layers_btn = widgets.Button(description="Clear Layers")
add_layer_btn = widgets.Button(description="Add Layer")
# Layer Threshold Slider (cal_min)
layer_thresh_slider = widgets.FloatSlider(
min=0.1, max=4.9, value=0.5, step=0.1, description="Layer Thresh"
)
# Layer Opacity Slider
layer_alpha_slider = widgets.FloatSlider(
min=0.1, max=1.0, value=0.7, step=0.1, description="Layer Opacity"
)
# Shader Selection
shader_dropdown = widgets.Dropdown(
options=nv.mesh_shader_names(), value="Phong", description="Shader"
)
# 4. Callbacks
def on_xray_change(change):
"""Handle xray change."""
nv.opts.mesh_xray = change["new"]
def on_vis_change(change):
"""Handle vis change."""
mesh_hemisphere.visible = change["new"]
def on_clear_layers_click(b):
"""Handle clear layers button."""
mesh_hemisphere.layers = []
def on_add_layer_click(b):
"""Handle add layer button."""
new_layer = MeshLayer(
path=DATA_FOLDER / "BrainMesh_ICBM152.lh.motor.mz3",
cal_min=0.5,
cal_max=5.5,
use_negative_cmap=True,
opacity=0.7,
colormap="warm",
colormap_negative="winter",
)
# Update the list trait to trigger synchronization (instead of using .append)
mesh_hemisphere.layers = [*mesh_hemisphere.layers, new_layer]
print(mesh_hemisphere.layers)
def on_layer_thresh_change(change):
"""Handle layer thresh change."""
if len(mesh_hemisphere.layers) > 0:
# Update the first layer's cal_min
mesh_hemisphere.layers[0].cal_min = change["new"]
def on_layer_alpha_change(change):
"""Handle layer alpha change."""
if len(mesh_hemisphere.layers) > 0:
# Update the first layer's opacity
mesh_hemisphere.layers[0].opacity = change["new"]
def on_shader_change(change):
"""Handle shader change."""
# Set shader for the first mesh
nv.set_mesh_shader(mesh_hemisphere.id, change["new"])
# 5. Bind Callbacks
xray_slider.observe(on_xray_change, names="value")
vis_checkbox.observe(on_vis_change, names="value")
clear_layers_btn.on_click(on_clear_layers_click)
add_layer_btn.on_click(on_add_layer_click)
layer_thresh_slider.observe(on_layer_thresh_change, names="value")
layer_alpha_slider.observe(on_layer_alpha_change, names="value")
shader_dropdown.observe(on_shader_change, names="value")
# 6. Display All
controls_row1 = widgets.HBox([xray_slider, vis_checkbox, add_layer_btn])
controls_row2 = widgets.HBox(
[layer_thresh_slider, layer_alpha_slider, clear_layers_btn]
)
controls_row3 = widgets.HBox([shader_dropdown])
layout = widgets.VBox([controls_row1, controls_row2, controls_row3, nv])
display(layout)